package com.yk.system.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yk.api.system.dto.DeviceDTO;
import com.yk.api.system.dto.GatewayDTO;
import com.yk.common.core.constant.NumberConstant;
import com.yk.common.core.domain.Result;
import com.yk.common.core.utils.LoginHelper;
import com.yk.system.convert.GatewayConvert;
import com.yk.system.entity.*;
import com.yk.system.service.*;
import com.yk.system.vo.GatewayAndDeviceStatusVO;
import com.yk.system.vo.GlobalStatusVO;
import com.yk.system.vo.IndexCountVO;
import com.yk.system.vo.IndexMapDataVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 首页控制器 yk-system
 *
 * @author lmx
 * @date 2023/11/8 16:33
 */
@Api(tags = "首页控制器")
@RestController
@RequiredArgsConstructor
@RequestMapping("/index")
public class IndexController {

    private final GatewayConvert gatewayConvert;
    private final DeviceRoleService deviceRoleService;
    private final AlarmHistoryService alarmHistoryService;
    private final DeviceService deviceService;
    private final VariableService variableService;
    private final TemplateService templateService;
    private final GatewayService gatewayService;
    private final VideoService videoService;
    private final ConfigurationService configurationService;


    @ApiOperation("首页-数据统计")
    @PostMapping("/count")
    public Result<IndexCountVO> count() {
        IndexCountVO indexCountDTO = new IndexCountVO();
        Long loginUserId = LoginHelper.getLoginUserId();
        // 网关数量
        long gatewayCount = gatewayService.count(new LambdaQueryWrapper<Gateway>()
                .eq(Gateway::getCreatedBy, loginUserId));
        indexCountDTO.setGatewayCount(gatewayCount);
        // 摄像头数量
        long videoCount = videoService.count(new LambdaQueryWrapper<Video>()
                .eq(Video::getCreatedBy, loginUserId));
        indexCountDTO.setVideoCount(videoCount);
        // 组态数量
        long configurationCount = configurationService.count(new LambdaQueryWrapper<Configuration>()
                .eq(Configuration::getCreatedBy, loginUserId));
        indexCountDTO.setConfigurationCount(configurationCount);
        // 存储型变量
        long variableCount = variableService.count(new LambdaQueryWrapper<Variable>()
                .eq(Variable::getCreatedBy, loginUserId)
                .eq(Variable::getStorage, NumberConstant.ONE));
        indexCountDTO.setVariableCount(variableCount);
        // 设备模型
        long templateCount = templateService.count(new LambdaQueryWrapper<Template>()
                .eq(Template::getCreatedBy, loginUserId));
        indexCountDTO.setTemplateCount(templateCount);
        // 设备数量
        List<DeviceDTO> list = deviceService.selectRole2Device();
        if (CollUtil.isEmpty(list)) {
            indexCountDTO.setDeviceCount(0L);
            indexCountDTO.setOnlineCount("0/0");
            indexCountDTO.setAlarmCount(0L);
        } else {
            String deviceCount = Integer.toString(list.size());
            indexCountDTO.setDeviceCount(Long.parseLong(deviceCount));
            long onlineCount = list.stream().filter(DeviceDTO::getStatus).count();
            // 设备在线率
            indexCountDTO.setOnlineCount(onlineCount + "/" + deviceCount);
            // 设备报警数
            List<Long> deviceIds = list.stream().map(DeviceDTO::getId).collect(Collectors.toList());
            long alarmCount = alarmHistoryService.count(new LambdaQueryWrapper<AlarmHistory>()
                    .in(AlarmHistory::getDeviceId, deviceIds)
                    .eq(AlarmHistory::getAlarmState, Boolean.TRUE));
            indexCountDTO.setAlarmCount(alarmCount);
        }
        return Result.data(indexCountDTO);
    }

    @ApiOperation("首页-地图数据")
    @PostMapping("/mapData")
    public Result<IndexMapDataVO> mapData() {
        IndexMapDataVO mapData = new IndexMapDataVO();
        Long loginUserId = LoginHelper.getLoginUserId();
        List<Gateway> gatewayList = gatewayService.list(new LambdaQueryWrapper<Gateway>().eq(Gateway::getCreatedBy, loginUserId));
        if (CollUtil.isEmpty(gatewayList)) {
            return Result.data(mapData);
        }
        List<GatewayDTO> dtoList = gatewayList.stream().map(gatewayConvert::entity2Dto).collect(Collectors.toList());
        AtomicInteger onlineCount = new AtomicInteger();
        AtomicInteger offlineCount = new AtomicInteger();
        AtomicInteger alarmCount = new AtomicInteger();
        dtoList.forEach(it -> {
            if (it.getStatus()) {
                onlineCount.getAndIncrement();
            } else {
                offlineCount.getAndIncrement();
            }
            LambdaQueryWrapper<Device> deviceLambda = new LambdaQueryWrapper<>();
            deviceLambda.select(Device::getId);
            deviceLambda.eq(Device::getGatewayId, it.getId());
            List<Device> list = deviceService.list(deviceLambda);
            if (CollUtil.isEmpty(list)) {
                return;
            }
            List<Long> ids = list.stream().map(Device::getId).collect(Collectors.toList());
            LambdaQueryWrapper<AlarmHistory> alarmLambda = new LambdaQueryWrapper<>();
            alarmLambda.eq(AlarmHistory::getAlarmState, Boolean.TRUE);
            alarmLambda.in(AlarmHistory::getDeviceId, ids);
            long count = alarmHistoryService.count(alarmLambda);
            if (count > 0) {
                alarmCount.getAndIncrement();
                it.setAlarmStatus(Boolean.TRUE);
            } else {
                it.setAlarmStatus(Boolean.FALSE);
            }
        });
        mapData.setOnlineCount(onlineCount.get());
        mapData.setOfflineCount(offlineCount.get());
        mapData.setAlarmCount(alarmCount.get());
        mapData.setGatewayList(dtoList);
        return Result.data(mapData);
    }

    @ApiOperation("全局网关、设备状态")
    @PostMapping("/gatewayAndDeviceStatus")
    public Result<GatewayAndDeviceStatusVO> gatewayAndDeviceStatus() {
        GatewayAndDeviceStatusVO vo = new GatewayAndDeviceStatusVO();
        Long loginUserId = LoginHelper.getLoginUserId();
        LambdaQueryWrapper<Gateway> gatewayLambda = new LambdaQueryWrapper<>();
        gatewayLambda.select(Gateway::getId, Gateway::getStatus);
        gatewayLambda.eq(Gateway::getCreatedBy, loginUserId);
        List<Gateway> gatewayList = gatewayService.list(gatewayLambda);
        List<GlobalStatusVO> gateWayList = Optional.ofNullable(gatewayList).orElse(Collections.emptyList()).stream().map(gateway -> {
            GlobalStatusVO gVo = new GlobalStatusVO();
            gVo.setId(gateway.getId());
            gVo.setStatus(gateway.getStatus());
            return gVo;
        }).collect(Collectors.toList());

        List<DeviceDTO> list = deviceService.selectRole2Device();
        List<GlobalStatusVO> deviceList = Optional.ofNullable(list).orElse(Collections.emptyList()).stream().map(device -> {
            GlobalStatusVO gVo = new GlobalStatusVO();
            gVo.setId(device.getId());
            gVo.setStatus(device.getStatus());
            return gVo;
        }).collect(Collectors.toList());
        vo.setGateWayList(gateWayList);
        vo.setDeviceList(deviceList);
        return Result.data(vo);
    }

}
